package LinkedList;

public class Josepfu {
    public static void main(String[] args) {
        CirclSingleLinkedList circlSingleLinkedList = new CirclSingleLinkedList();
        circlSingleLinkedList.addBoy(10);
        circlSingleLinkedList.showBoy();
        System.out.println("出圈");
        circlSingleLinkedList.countBoy(10,5,10);
    }
}
class CirclSingleLinkedList{
    //创建一个first节点，当前没有编号
    private Boy first = null;

    //添加小孩子节点,构成一个环形的链表
    public void addBoy(int nums){
        //nums 做一个数据校验
        if (nums < 1){
            System.out.println("nums的值不正确");
            return;
        }
        Boy curBoy = null;//辅助指针，帮助构建环形链表
        for (int i = 1; i <= nums ; i++) {
            //根据编号，创建小孩节点
            Boy boy = new Boy(i);
            //如果是第一小孩
            if (i == 1){
                first = boy;
                first.setNext(first);//构成环
                curBoy = first;//让curBody指向第一个小孩
            }else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    /**
     * 遍历当前的环形链表
     */
    public void showBoy(){
        //判断链表是否为空
        if (first == null){
            System.out.println("没有任何小孩```");
            return;
        }
        //因为first不能动，因此我们任然使用一个辅助指针完成遍历
        Boy curBody = first;
        while(true){
            System.out.printf("小孩的编号 %d\n",curBody.getNo());
            if (curBody.getNext() == first){
                //说明已经遍历完毕
                break;
            }
            curBody = curBody.getNext();
        }
    }

    /**
     *
     * @param startNo 从第几个小孩开始
     * @param countNum 出几个
     * @param nums     原来有几个小孩
     */
    public void countBoy(int startNo,int countNum,int nums){
        //先对数据进行校验
        if (first == null || startNo<1||countNum>nums){
            System.out.println("胡整啥！！！");
            return;
        }
        //创建辅助指针  让其指向最后一个小孩
        Boy helper = first;
        while (true){
            if (helper.getNext() == first){
                break;
            }
            helper = helper.getNext();
        }
        //让first指向第一个开始报数的同学
        for (int i = 0; i < startNo - 1 ; i++) {
            first = first.getNext();
            helper = helper.getNext();//helper 相当于链表的尾巴
        }

        while (true){
            if (helper == first){
                //说明只剩一个节点
                break;
            }
            for (int i = 0; i < countNum-1; i++) {
                first = first.getNext();
                helper = helper.getNext();
            }

            System.out.printf("小孩 %d 出圈\n",first.getNo());
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.printf("最后留在圈中的小孩 %d \n",first.getNo());

    }
}

/**
 * 创建一个Boy类，表示一个节点
 */
class Boy{
    private int no;//编号
    private Boy next;//指向下一个节点默认Null

    public Boy(int no) {
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Boy getNext() {
        return next;
    }

    public void setNext(Boy next) {
        this.next = next;
    }
}
